package com.thinkTank.oa.controller;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.context.ServletContextAware;

import com.github.pagehelper.StringUtil;
import com.thinkTank.oa.common.Constant;
import com.thinkTank.oa.common.SystemGlobals;
import com.thinkTank.oa.common.UserInfo;
import com.thinkTank.oa.entity.Dictiontry;
import com.thinkTank.oa.entity.Operationlog;
import com.thinkTank.oa.entity.Person;
import com.thinkTank.oa.entity.User;
import com.thinkTank.oa.entity.UserLook;
import com.thinkTank.oa.service.OperationlogService;
import com.thinkTank.oa.service.UserLookService;
import com.thinkTank.oa.service.UserService;
import com.thinkTank.oa.util.StrUtil;

@Controller
public class BaseController implements ServletContextAware {

	@Autowired
	protected UserService userService;
	@Autowired
	private UserLookService userLookService;
	@Autowired
	protected OperationlogService operationlogService;

	/**
	 * 默认记录数
	 */
	public static final int DEFAULT_COUNT = 10;

	public ServletContext getServletContext() {
		return servletContext;
	}

	private ServletContext servletContext;

	@Override
	public void setServletContext(ServletContext context) {
		this.servletContext = context;
	}

	protected String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		return ip;
	}

	/**
	 * 从系统缓存中获取项目来源下拉列表取值
	 * 
	 * @author dq
	 * @date 2018-08-08
	 * @return 项目来源
	 */
	public List<Dictiontry> getProjectSorce() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_PROJECTSOURCE);
	}

	/**
	 * 从系统缓存中获取省
	 * 
	 * @author dq
	 * @date 2018-08-08
	 * @return 返回所有的省
	 */
	public List<Dictiontry> getAreaProvince() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_AREA_PROVINCE);
	}

	/***
	 * 根据 参数 ProvinceId 查询相关的市
	 * 
	 * @param ProvinceId
	 *            省的Id
	 * @author dq
	 * @date 2018-08-09
	 * @return 返回和省相关的市区
	 */
	protected List<Dictiontry> getCityByProvince(String provinceId) {
		List li = new ArrayList<Dictiontry>();
		List<Dictiontry> list = SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_AREA_CITY);
		for (Dictiontry ll : list) {
			if (ll.getParentId().equals(provinceId)) {
				li.add(ll);
			}
		}
		return li;
	}

	/***
	 * 根据 参数 cityId 查询相关的区
	 * 
	 * @param cityId
	 *            市的Id
	 * @author dq
	 * @date 2018-08-09
	 * @return 返回和市相关的区
	 */
	protected List<Dictiontry> getAreaByCity(String cityId) {
		List li = new ArrayList<Dictiontry>();
		List<Dictiontry> list = SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_AREA);
		for (Dictiontry ll : list) {
			if (ll.getParentId().equals(cityId)) {
				li.add(ll);
			}
		}
		return li;
	}

	/***
	 * 在session中获取当前登录用的userId
	 * 
	 * @param request
	 * @return
	 */
	public String getUserId(HttpServletRequest request) {
		UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo");
		if (userInfo != null) {
			return userInfo.getUserId();
		} else {
			UserDetails userDetails = (UserDetails) SecurityContextHolder.getContext().getAuthentication()
					.getPrincipal();
			User user = userService.getUserByUsername(userDetails.getUsername());
			UserInfo userInfo1 = new UserInfo();
			userInfo1.setFullName(user.getFullName());
			userInfo1.setUserId(user.getPid());
			request.getSession().setAttribute("userInfo", userInfo1);
			return userInfo1.getUserId();
		}
	}

	/**
	 * 从session里面取登录信息
	 * 
	 * @param request
	 * @return
	 */
	public UserInfo getUserInfoBySession(HttpServletRequest request) {
		UserInfo userInfo = (UserInfo) request.getSession().getAttribute("userInfo");
		return userInfo;
	}

	/**
	 * 获取所属领域
	 * 
	 * @author pdz
	 * @date 2018年8月13日
	 * @return
	 */
	public List<Dictiontry> getResearchField() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_PROJECTFIELD);
	}

	/**
	 * 获取客户来源
	 */
	public List<Dictiontry> getCustomerSource() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_CUSTOMERSOURCE);
	}

	/**
	 * 获取客户类型
	 */
	public List<Dictiontry> getCustomerType() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_CUSTOMERTYPE);
	}

	/**
	 * 从系统缓存中获取专家类型的下拉列表取值
	 * 
	 * @author 董力
	 * @date 2018-8-16
	 * @return 专家类型
	 */
	public List<Dictiontry> getPersonType() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_PERSONTYPE);
	}

	/**
	 * 从系统缓存中获取人才级别的下拉列表取值
	 * 
	 * @author 董力
	 * @date 2018-8-16
	 * @return 人才级别
	 */
	public List<Dictiontry> getTalentLevel() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_TALENTLEVEL);
	}

	/**
     * 从系统缓存中获取对接状态的下拉列表取值
     * @author dongli
     * @date 2018年8月20日
     * @return
     */
    public List<Dictiontry> getButtStatus(){
    	return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_BUTTSTATUS);
    }
    
    /**
	 * 根据区的id，返回parent市的信息
	 * 
	 * @param areaId
	 * @return
	 */
	public List<Dictiontry> getCityByAreaId(String areaId) {
		List<Dictiontry> list = SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_AREA);
		List<Dictiontry> citylist = SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_AREA_CITY);
		String parentCity = "";
		String provinceId = "";
		for (Dictiontry dictiontry : list) {
			if (areaId.equals(dictiontry.getNames())) {
				parentCity = dictiontry.getParentId();
				break;
			}
		}
		for (Dictiontry dictiontry : citylist) {
			if (parentCity.equals(dictiontry.getNames())) {
				provinceId = dictiontry.getParentId();
				break;
			}
		}
		return getCityByProvince(provinceId);
	}

	/**
	 * 获取客户性质
	 */
	public List<Dictiontry> getCustomerNature() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_CUSTOMERNATURE);
	}
	
	/**
	 * 获取意向合作方式
	 */
	public List<Dictiontry> getIntentionCooperate() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_INTENTIONCOOPERATE);
	}
	
	
	/**
	 * 获取当前合作状态
	 */
	public List<Dictiontry> getCurrentState() {
		return SystemGlobals.getInstance().getDictiontryMap(Constant.DICTIONTRY_CURRENTSATUS);
	}
	
	   /**
     * 将地区放在model中以便在页面回显，会根据domesticOrForeign的值自动判断国内国外,根据areaStr的值自动判断省市区
     * @author pdz
     * @date 2018年8月21日
     * @param model
     * @param areaId 从数据库中查出来的地区的数字值
	 * @param domesticOrForeign 国内还是国外，0表示国内，1表示国外
     */
    protected void areaModel(Model model, String areaId, Integer domesticOrForeign) {
        if (domesticOrForeign == 0) {
            String province = areaId.substring(0, 2);
            String city = areaId.length() > 2 ? areaId.substring(0, 5) : null;
            String area = areaId.length() == 9 ? areaId : null;
            List<Dictiontry> cityDictiontryList = province != null ? getCityByProvince(province) : new ArrayList<>();
            List<Dictiontry> areaDictiontryList = city != null ? getAreaByCity(city) : new ArrayList<>();
            model.addAttribute("province", province);
            model.addAttribute("city", city);
            model.addAttribute("district", area);
            model.addAttribute("cityDictiontryList", cityDictiontryList);
            model.addAttribute("areaDictiontryList", areaDictiontryList);
        } else {
            model.addAttribute("country", Integer.parseInt(areaId));
        }
    }
    
    /**
     * 返回地区的字符串值，国内如:湖北-武汉市  国外如：美国
     * @author pdz
     * @date 2018年9月7日
     * @param areaId
     * @param domesticOrForeign
     * @return
     */
    public String getAreaWorth(String areaId, Integer domesticOrForeign) {
    	if (StringUtil.isEmpty(areaId))
    		return null;
        if (domesticOrForeign == 0) {
            String provinceId = areaId.substring(0, 2);
            String province = getAreaWorth(provinceId, Constant.DICTIONTRY_AREA_PROVINCE);
            String cityId = areaId.length() > 2 ? areaId.substring(0, 5) : null;
            String city = cityId != null ? getAreaWorth(cityId, Constant.DICTIONTRY_AREA_CITY) : "";
            String districtId = areaId.length() == 9 ? areaId : null;
            String disctrict = districtId != null ? getAreaWorth(districtId, Constant.DICTIONTRY_AREA) : "";
            return Stream.of(province, city, disctrict).filter(StringUtil::isNotEmpty).collect(Collectors.joining("-"));
        } else 
            return getDicSingleWorth(Integer.parseInt(areaId), Constant.DICTIONTRY_COUNTRY);
    }
    
    /**
     * 获取地区的worth
     * @author pdz
     * @date 2018年9月10日
     * @param areaId 地区的数字编号
     * @param groupname 地区的分组
     * @return
     */
    public String getAreaWorth(String areaId, String groupname) {
        List<Dictiontry> dicList = SystemGlobals.getInstance().getDictiontryMap(groupname);
        return dicList.stream().filter(dic -> areaId.equals(dic.getNames())).map(Dictiontry::getWorth).findAny().get();
    }
    
    
    /**
     * 请使用getDicWorth方法
     * 获取字典表中的worth值
     * @author pdz
     * @date 2018年8月22日
     * @param typeId 查出来的十进制字符串,数据库里面存的是二进制类型，查出来会自动变成十进制
     * @param dictiontryList 字典表中某个分组的集合
     * @return
     */
    @Deprecated
    public String getDictiontryWorth(String typeId, List<Dictiontry> dictiontryList) {
        return Stream.of(StrUtil.byteToString(typeId).split(","))
            .map(singleTypeId -> dictiontryList.stream()
                                               .filter(ptd -> ptd.getNames().equals(singleTypeId)).map(Dictiontry::getWorth).findAny().get())
            .collect(Collectors.joining(","));
    }
    
    /**
     * 获取字典表中的worth值,适用于保存的是字典表中的names，但不适用于地区，地区用getAreaWorth
     * @author pdz
     * @date 2018年9月7日
     * @param checkboxId 查出来的十进制数字字符串，这些字符串保存的页面上的复选框
     * @param groupname 分组名称，用Constant中的常量
     * @return
     */
    public String getDicCheckboxWorth(String checkboxId, String groupname) {
    	if (StringUtil.isEmpty(checkboxId))
    		return null;
        List<Dictiontry> dicList = SystemGlobals.getInstance().getDictiontryMap(groupname);
        return Stream.of(StrUtil.byteToString(checkboxId).split(","))
                .map(singleId -> dicList.stream().filter(dic -> dic.getNames().equals(singleId)).map(Dictiontry::getWorth).findAny().get())
                .collect(Collectors.joining(","));
    }
    
    /**
     * 获取字典表中的worth值,适用于存储的是字典中的pid
     * @author pdz
     * @date 2018年9月7日
     * @param numId 查出来的数字值
     * @param groupname 分组名称，用Constant中的常量
     * @return
     */
    public String getDicSingleWorth(Integer numId, String groupname) {
    	if (numId == null)
    		return null;
        List<Dictiontry> dicList = SystemGlobals.getInstance().getDictiontryMap(groupname);
        return dicList.stream().filter(dic -> numId.equals(dic.getPid())).map(Dictiontry::getWorth).findAny().get();
    }
    
    /**
     * 获取对接状态的worth值，因为对接状态和别的不一样，存的是names，所以单独写一个方法
     * @author pdz
     * @date 2018年11月20日
     * @param status
     * @return
     */
    public String getButtStatusWorth(Integer status) {
    	return getDicList(Constant.DICTIONTRY_BUTTSTATUS).stream().filter(dic -> dic.getNames().equals(status.toString()))
    			.map(Dictiontry::getWorth).findAny().get();
    }
    
    /**
     * 判断person是否存在4中联系方式中的任一联系方式
     * @author pdz
     * @date 2018年9月11日
     * @param person
     * @return
     */
    public boolean hasContact(Person person) {
        List<String> contactList = new ArrayList<>();
        contactList.add(person.getFixedPhone());
        contactList.add(person.getTell());
        contactList.add(person.getWechat());
        contactList.add(person.getEmail());
//        contactList.add(person.getOtherContact());
        return contactList.stream().anyMatch(StringUtil::isNotEmpty);
    }
    
    /**
     * 返回groupname分组的dictionary集合，并按sort升序排列
     * @author pdz
     * @date 2018年10月22日
     * @param groupname 常量
     * @return
     */
    public List<Dictiontry> getDicList(String groupname) {
    	return SystemGlobals.getInstance().getDictiontryMap(groupname).stream().filter(dic -> dic.getSort() != null)
    			.sorted(Comparator.comparingInt(Dictiontry::getSort)).collect(Collectors.toList());
	}
    
    public void checkLookExpert(String expertId, String lookPwd, HttpServletRequest request) {
    	User user = userService.getById(getUserId(request));
    	String[] arr = user.getLookNumber().split("-");
    	//一天免密查看数量
    	int lookFreeNumber = Integer.parseInt(arr[0]);
    	//一天查看的上限
    	int lookAllNumber = Integer.parseInt(arr[1]);
    	//查询已经查看成功过的，查询的时候时间到天，存储到秒
    	UserLook userLook = new UserLook().setUserId(getUserId(request)).setTime(StrUtil.getCurrentDateTime("yyyy-MM-dd")).setRemark1("查看成功");
    	List<UserLook> userLookList = userLookService.queryAll(userLook);
    	List<String> expertIdList = userLookList.stream().map(UserLook::getExpertId).distinct().collect(Collectors.toList());
    	//是否可以查看，1表示可以，0不可以
    	int isLook = expertIdList.size() < lookAllNumber || expertIdList.contains(expertId) ? 1 : 0;
    	//是否需要密码，1需要，0不需要
    	int isSign = expertIdList.size() >= lookFreeNumber && expertIdList.size() < lookAllNumber && !expertIdList.contains(expertId) ? 1 : 0;
    	//密码是否正确，1正确，0错误
    	int isLookPwd = -1;
    	if (isLook == 1) {
    		if (isSign == 1 && StringUtil.isNotEmpty(lookPwd)) {
    			isLookPwd = lookPwd.equals(user.getLookPwd()) ? 1 : 0;
    			if (isLookPwd == 1)
    				isSign = 0;
    		}
    		if (isSign == 0 || (isSign == 1 && StringUtil.isNotEmpty(lookPwd))) {
    			userLook.setExpertId(expertId).setPid(StrUtil.getUUID32()).setIp(getIpAddr(request))
    			.setTime(StrUtil.getCurrentDateTime_two()).setRemark1(isSign == 0 || (isSign == 1 && isLookPwd == 1) ? "查看成功" : "密码错误，查看失败："+lookPwd);
    			userLookService.add(userLook);
    		}
    	}
    	request.setAttribute("isLook", isLook);
    	request.setAttribute("isSign", isSign);
    	request.setAttribute("isLookPwd", isLookPwd);
    }
    
    /**
     * 返回修改的主键集合
     * @author pdz
     * @date 2018年11月28日
     * @param beginDate
     * @param endDate
     * @param userId
     * @param operaIndex
     * @return
     */
    public List<String> queryUpdateLog(String beginDate, String endDate, String userId, Integer operaIndex) {
    	List<String> operaList = Arrays.asList("修改项目", "修改需求", "修改客户", "修改专家", "修改对接详情");
    	Operationlog operationlog = new Operationlog(operaList.get(operaIndex), userId, beginDate, endDate);
    	List<Operationlog> list = operationlogService.queryAll(operationlog);
    	return list.stream().map(Operationlog::getRefPid).collect(Collectors.toList());
    }
    
}
